using System;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Xml;

using Google.GData.Photos;
using Google.GData.Extensions.MediaRss;

using Microsoft.MediaCenter;
using Microsoft.MediaCenter.UI;

using System.Runtime.InteropServices;

using GalleryItem = McePicasa.GalleryItem;
using Filter = McePicasa.Filter;
using DetailsCommand = McePicasa.DetailsCommand;
using McePicasa.mceFlickr;
using FlickrNet;

namespace McePicasa
{

    /// <summary>
    /// The User experience within the McePicasa application.
    /// </summary>
    public class User : ApplicationExperience, IDisposable
    {
        //[DllImport("kernel32.dll")] static extern bool OutputDebugString(string txt);

        /// <summary>
        /// Construct a User experience.
        /// </summary>
        /// 
        public User()
        {
            base.Description = "User Albums";
        }
        public User(FlickrUser flickrUser)
        {
            this.flickrUser = flickrUser;
            base.Description = flickrUser.UserName;
        }

        public User(PicasaUser piUser)
        {
            this.picasaUser = piUser;
            base.Description = piUser.Id2;
        }

        #region Menu Category

        /// <summary>
        /// Create the main menu category entry for this experience.
        /// </summary>
        public override MenuCategory CreateMenuCategory()
        {
            MenuCategory category = new MenuCategory();
            FlickrAPI fa = null;
            Photosets ps = null;
            

            // Title
            category.Title = Description;

            if (picasaUser == null && flickrUser == null)
            {
                category.Subtitle = "Click on either Picasa or Flickr";
            }
            else if(picasaUser == null && flickrUser != null)
            {
                fa = new FlickrAPI();
                ps = fa.GetUsersPhotosets(flickrUser.UserName);
                category.Subtitle = ps.PhotosetCollection.Length.ToString(CultureInfo.CurrentCulture);
            }
            else if(picasaUser != null && flickrUser == null)
            {
                category.Subtitle = picasaUser.NoOfAlbums.ToString(CultureInfo.CurrentCulture);
            }
            //category.Subtitle = (picasaUser == null) ? "Any public album" : picasaUser.NoOfAlbums.ToString(CultureInfo.CurrentCulture);

            //
            // Featured items
            //

            VirtualList items = new VirtualList(category, null);
            items.EnableSlowDataRequests = true;
            
            items.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteAlbumGalleryItem);
            category.SetItems(items);

            if (picasaUser != null)
            {
                for (int i = 0; i < picasaUser.NoOfAlbums; i++)
                {
                    items.Add(CreateAlbumGalleryItem(category, picasaUser.GetAlbum(i)));
                    // Stop once we've found 3 items.
                    if (category.Items.Count >= 3) break;
                }
            }
            else if(flickrUser == null && picasaUser == null)
            {
                items.Add(CreateAlbumGalleryItem(category, null as PicasaAlbum));
                items.Add(CreateAlbumGalleryItem(category, null as FlickrAlbum));
            }


            if (flickrUser != null)
            {
                

                for (int i = 0; i < ps.PhotosetCollection.Length; i++)
                {
                    FlickrAlbum album = new FlickrAlbum();
                    album.PhotoSets = new List<Photoset>();
                    album.PhotoSets.Add(ps.PhotosetCollection[i]);
                    items.Add(CreateAlbumGalleryItem(category, album));
                    // Stop once we've found 3 items.
                    if (category.Items.Count >= 3) break;
                }
            }
            

            //
            // Set up a handler for when this category is clicked.
            //

            category.Invoked += delegate(object sender, EventArgs args)
            {
                Application.Current.CurrentUser = this;
                if (picasaUser == null)
                {
                    //Application.Current.GoToLogOn0(this, category);
                }
                else
                {
                    // Go to our album gallery page.
                    GalleryPage page = CreateAlbumGalleryPage(category);
                    Application.Current.GoToGallery(page);
                }
            };
            return category;
        }

        #endregion Menu Category

        #region album Gallery

        /// <summary>
        /// Create the gallery page for this exprience.
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public GalleryPage CreateAlbumGalleryPage(MenuCategory category)
        {
            GalleryPage page = new GalleryPage(category);
            page.Description = Description;

            // Create the virtual list and enable slow data.
            VirtualList galleryList = new VirtualList(page, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteAlbumGalleryItem);
            page.SetContent(galleryList);

            // Create and apply the filters.
            CreateAlbumGalleryFilters(page);

            return page;
        }

        /// <summary>
        /// Create the gallery page for this exprience. FLICKR
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public GalleryPageFlickr CreateAlbumGalleryPageFlickr(MenuCategory category)
        {


            GalleryPageFlickr page = new GalleryPageFlickr(category);
            page.Description = Description;

            // Create the virtual list and enable slow data.
            VirtualList galleryList = new VirtualList(page, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteAlbumGalleryItem);
            page.SetContent(galleryList);

            // Create and apply the filters.
           CreateAlbumGalleryFilters(page);

            return page;
        }


        /// <summary>
        /// Creat the filters on the gallery.
        /// </summary>
        private void CreateAlbumGalleryFilters(GalleryPage page)
        {
            //
            // Put together a list of filters on the content.
            //
            ArrayListDataSet list = new ArrayListDataSet(page);

            // Create the unfiltered "All" filter
            ModelItem filterAll = new Filter(page, "All", -1);
            list.Add(filterAll);

            ModelItem filterTags = new Filter(page, "Tags", -1);
            list.Add(filterTags);

            // FUTURE: There's information in the data table for us to implement
            // a "featured" filter.  Its implementation would go here.

            Choice filters = new Choice(page, null, list);
            filters.Chosen = filterAll;

            //
            // Hook up the "filter changed" event so that we can apply the
            // active filter to our gallery.
            //
            // As soon as this Filters list is set, we will get an OnActiveFilterChanged
            // event which will cause us to populate the gallery.
            //

            page.SetActiveFilterChanged(delegate(object sender, EventArgs e)
            {
                GalleryPage galleryPage = (GalleryPage)sender;
                Filter activeFilter = (Filter)galleryPage.Filters.Chosen;
                FilterContent(galleryPage, activeFilter.FilterId);
            });
            page.Filters = filters;
        }


        /// <summary>
        /// Creat the filters on the gallery flickr.
        /// </summary>
        private void CreateAlbumGalleryFilters(GalleryPageFlickr page)
        {
            //
            // Put together a list of filters on the content.
            //
            ArrayListDataSet list = new ArrayListDataSet(page);

            // Create the unfiltered "All" filter
            ModelItem filterAll = new Filter(page, "All", -1);
            list.Add(filterAll);

            ModelItem filterTags = new Filter(page, "Tags", -1);
            list.Add(filterTags);

            // FUTURE: There's information in the data table for us to implement
            // a "featured" filter.  Its implementation would go here.

            Choice filters = new Choice(page, null, list);
            filters.Chosen = filterAll;

            //
            // Hook up the "filter changed" event so that we can apply the
            // active filter to our gallery.
            //
            // As soon as this Filters list is set, we will get an OnActiveFilterChanged
            // event which will cause us to populate the gallery.
            //

            page.SetActiveFilterChanged(delegate(object sender, EventArgs e)
            {
                GalleryPageFlickr galleryPage = (GalleryPageFlickr)sender;
                Filter activeFilter = (Filter)galleryPage.Filters.Chosen;
                FilterContent(galleryPage, activeFilter.FilterId);
            });
            page.Filters = filters;
        }

        /// <summary>
        /// Populate the gallery's content given the current filer.
        /// </summary>
        private void FilterContent(GalleryPage page, int filterId)
        {
            //To be implemented in the future
            page.Content.Clear();

            for (int i = 0; i < picasaUser.NoOfAlbums; i++)
            {
                PicasaAlbum album = picasaUser.GetAlbum(i);
                page.Content.Add(CreateAlbumGalleryItem(page, album));
            }

            Log.LogIt("FilterContent: filterId = " + filterId.ToString(CultureInfo.CurrentCulture));

            return;
        }

        /// <summary>
        /// Populate the gallery's content given the current filer.
        /// </summary>
        private void FilterContent(GalleryPageFlickr page, int filterId)
        {
            //To be implemented in the future
            page.Content.Clear();

            FlickrAPI fa = new FlickrAPI();
            Photosets ps = fa.GetUsersPhotosets(flickrUser.UserName);
            
            int i = 0;
            foreach (Photoset item in ps.PhotosetCollection)
	        {
                FlickrAlbum album = new FlickrAlbum();
                album.PhotoSets = new List<Photoset>();
                
                album.PhotoSets.Add(item); //ps.PhotosetCollection[i];

                page.Content.Add(CreateAlbumGalleryItem(page, album));
                i++;
	        }    
            //album.Photos.PhotoCollection = ps.PhotosetCollection;
            //    page.Content.Add(CreateAlbumGalleryItem(page, album));


            ////for (int i = 0; i < flickrUser. .NoOfAlbums; i++)
            //for (int i = 0; i < 1; i++)
            //{
            //    FlickrAPI fa = new FlickrAPI();
            //    Photosets ps = fa.GetUsersPhotosets(flickrUser.UserName);

            //    Photoset album = ps.PhotosetCollection. //picasaUser.GetAlbum(i);
            //    page.Content.Add(CreateAlbumGalleryItem(page, album));
            //}

            Log.LogIt("FilterContent: filterId = " + filterId.ToString(CultureInfo.CurrentCulture));

            return;
        }

        /// <summary>
        /// Create a gallery item from a row in the table.
        /// </summary>
        private GalleryItem CreateAlbumGalleryItem(ModelItem page, PicasaAlbum album)
        {
            GalleryItem item = new GalleryItem(page, album);
            //
            // Hook up an event for when the gallery item is invoked.
            //

            item.Invoked += delegate(object sender, EventArgs args)
            {
                if (album == null)
                {
                    Application.Current.GoToLogOn0(this, page as MenuCategory);
                }
                else
                {
                    Application.Current.CurrentUser = this;
                    GalleryItem galleryItem = (GalleryItem)sender;
                    // Navigate to a gallery page for this album.
                    GalleryPage galleryPage = CreatePhotoGalleryPage(galleryItem);
                    Application.Current.GoToGallery(galleryPage);
                }
            };
            return item;
        }

        /// <summary>
        /// Create a gallery item from a row in the table flickr.
        /// </summary>
        private GalleryItemFlickr CreateAlbumGalleryItem(ModelItem page, FlickrAlbum album)
        {
            GalleryItemFlickr item = new GalleryItemFlickr(page, album);
            //
            // Hook up an event for when the gallery item is invoked.
            //

            item.Invoked += delegate(object sender, EventArgs args)
            {
                if (album == null)
                {
                    Application.Current.GoToLogOn1(this, page as MenuCategory);
                }
                else
                {
                    Application.Current.CurrentUser = this;
                    GalleryItemFlickr galleryItem = (GalleryItemFlickr)sender;
                    // Navigate to a gallery page for this album.
                    GalleryPageFlickr galleryPage = CreatePhotoGalleryPageFlickr(galleryItem);
                    Application.Current.GoToGallery(galleryPage);
                }
            };
            return item;
        }

        /// <summary>
        /// Finishes any slow data for a gallery item.
        /// </summary>
        private void CompleteAlbumGalleryItem(VirtualList list, int index)
        {
            try
            {
                if (list[index].GetType().Equals(typeof(GalleryItemFlickr)))
                {
                    GalleryItemFlickr item = (GalleryItemFlickr)list[index];
                    if (item.Album == null)
                    {
                        //item.Image = new Image(Global.IconImagePath);
                        item.Image = new Image(Global.IconImagePathFlickr);
                    }
                    else
                    {
                        if (item.Album.PhotoSets != null && item.Album.PhotoSets.Count > 0)
                        {
                            item.Image = new Image(item.Album.PhotoSets[0].PhotosetSmallUrl);
                        }
                        else
                        {
                            item.Image = new Image(item.Album.Photos.PhotoCollection[0].SmallUrl);
                        }
                    }
                    
                }
                else
                {
                    GalleryItem item = (GalleryItem)list[index];
                    item.Image = item.Album == null ? new Image(Global.IconImagePath) : item.Album.LoadImage();
                }
               
            }
            catch (IOException e)
            {
                Log.LogIt(e.Message);
                Global.MsgBox(e.Message, 10);
            }
        }
       
        #endregion album Gallery

        #region photo Gallery

        /// <summary>
        /// Create a gallery of photos from a album.
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public GalleryPage CreatePhotoGalleryPage(GalleryItem item)
        {
            GalleryPage page = new GalleryPage(item);
            PicasaAlbum album = item.Album;
            page.Description = album.MyTitle;

            // Create the virtual list and enable slow data.
            VirtualList galleryList = new VirtualList(page, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompletePhotoGalleryItem);
            page.SetContent(galleryList);

            // No filters in the photo gallery
            //page.Filters = null;

            //
            // Create all the gallery items.
            //

            //string Url = album.MyUrl;
            album.LoadPhotos();
            for (int i = 0; i < album.NoOfPhotos; i++)
            {
                PicasaPhoto photo = album.GetPhoto(i);
                page.Content.Add(CreatePhotoGalleryItem(page, photo));
            }

            SetupPrevAndNextItems(page);

            return page;
        }


        /// <summary>
        /// Create a gallery of photos from a album. flickr
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public GalleryPageFlickr CreatePhotoGalleryPageFlickr(GalleryItemFlickr item)
        {
            GalleryPageFlickr page = new GalleryPageFlickr(item);
            FlickrAPI fa = new FlickrAPI();

            item.Album.PhotoSets[0] = fa.GetPhotosetPhotos(item.Album.PhotoSets[0].PhotosetId);
            FlickrAlbum album = item.Album;
            if (item.Photo != null)
            {
                page.Description = item.Photo.Title;//album.MyTitle;
            }
            else
            {
                page.Description = item.Album.PhotoSets[0].Title;

            }
            
            

            // Create the virtual list and enable slow data.
            VirtualList galleryList = new VirtualList(page, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompletePhotoGalleryItemFlickr);
            page.SetContent(galleryList);

            // No filters in the photo gallery
            //page.Filters = null;

            //
            // Create all the gallery items.
            //

            //string Url = album.MyUrl;
            //album.LoadPhotos();
            //for (int i = 0; i < album.NoOfPhotos; i++)
            //{
            foreach (Photo photoItem in album.PhotoSets[0].PhotoCollection)
            {
                page.Content.Add(CreatePhotoGalleryItemFlickr(page, photoItem));
            }

            SetupPrevAndNextItemsFlickr(page);

            //Photo photo = null;//album.PhotoSets[0].PhotoCollection[0]; //album.GetPhoto(i);
                
           // }

            return page;
        }


        /// <summary>
        /// Create a gallery item from a row of photo data.
        /// </summary>
        private GalleryItem CreatePhotoGalleryItem(ModelItem page, PicasaPhoto photo)
        {
            GalleryItem item = new GalleryItem(page, photo);
            //
            // Hook up an event for when the gallery item is invoked.
            //

            item.Invoked += delegate(object sender, EventArgs args)
            {
                Application.Current.CurrentUser = this;
                GalleryItem galleryItem = (GalleryItem)sender;
                // Navigate to a details page for this photo.
                DetailsPage detailsPage = CreatePhotoDetailsPage(galleryItem, false);
                Application.Current.GoToDetails(detailsPage);
            };

            return item;
        }

        /// <summary>
        /// Create a gallery item from flickr photo
        /// </summary>
        private GalleryItemFlickr CreatePhotoGalleryItemFlickr(ModelItem page, Photo photo)
        {
            GalleryItemFlickr item = new GalleryItemFlickr(page, photo);
            //
            // Hook up an event for when the gallery item is invoked.
            //

            item.Invoked += delegate(object sender, EventArgs args)
            {
                Application.Current.CurrentUser = this;
                GalleryItemFlickr galleryItem = (GalleryItemFlickr)sender;
                // Navigate to a details page for this photo.
                DetailsPageFlickr detailsPage = CreatePhotoDetailsPageFlickr(galleryItem, false);
                Application.Current.GoToDetails(detailsPage);
            };

            return item;
        }

        /// <summary>
        /// Create a gallery item from flickr photo with prev/next photos
        /// </summary>
        private GalleryItemFlickr CreatePhotoGalleryItemFlickr(ModelItem page, Photo photo, Photo prePhoto, Photo nextPhoto)
        {
            GalleryItemFlickr item = new GalleryItemFlickr(page, photo, prePhoto, nextPhoto);
            //
            // Hook up an event for when the gallery item is invoked.
            //

            item.Invoked += delegate(object sender, EventArgs args)
            {
                Application.Current.CurrentUser = this;
                GalleryItemFlickr galleryItem = (GalleryItemFlickr)sender;
                // Navigate to a details page for this photo.
                DetailsPageFlickr detailsPage = CreatePhotoDetailsPageFlickr(galleryItem, false);
                Application.Current.GoToDetails(detailsPage);
            };

            return item;
        }



        /// <summary>
        /// Finishes any slow data for an photo gallery item.
        /// </summary>
        private void CompletePhotoGalleryItem(VirtualList list, int index)
        {
            GalleryItem item = (GalleryItem)list[index];
            if (item.Photo != null)
                item.Image = item.Photo.LoadImage(true);
            else
                item.Image = null;
        }

        /// <summary>
        /// Finishes any slow data for an photo gallery item.
        /// </summary>
        private void CompletePhotoGalleryItemFlickr(VirtualList list, int index)
        {
            GalleryItemFlickr item = (GalleryItemFlickr)list[index];
            if (item.Photo != null)
                item.Image = new Image(item.Photo.SmallUrl);
            else
                item.Image = null;
        }

        #endregion photo Gallery

        #region photo Details

        /// <summary>
        /// Create a details page for an photo.
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public DetailsPage CreatePhotoDetailsPage(GalleryItem item, bool isOnSlideshow)
        {
            DetailsPage page = new DetailsPage(item, isOnSlideshow);

            //
            // Get the full metadata on the photo.
            //
            //And
            //
            // Fill in the page's easy properties.
            //

            PhotoAccessor pa = item.Photo.PhotoAccessor;
            DateTime dt = new DateTime(1970, 1, 1).AddMilliseconds(pa.Timestamp);
            page.Title = item.Photo.MyTitle;
            page.Summary = pa.PhotoSummary;// item.Photo.Description;
            page.Background = item.Photo.LoadImage(false);
            //page.DetailsPageStatusText = "";
            //page.Owner = item;

            //
            // Metadata
            //
            // Now that we have all the little pieces, we can put together our
            // final metadata string.
            //
            int w = int.Parse(Global.Imgmax, CultureInfo.CurrentCulture);
            if (w > pa.Width) w = pa.Width;
            page.Metadata = String.Format(CultureInfo.CurrentCulture, "{0}\n{1}\n{2:g}\n{3}\n{4}\n{5}",
                String.Format(CultureInfo.CurrentCulture, "{0}KB ({1}x{2})", (int)(item.Photo.DownloadFileSize / 1024),
                    w, pa.Width == 0 ? w : (int)(w * pa.Height / pa.Width)),
                String.Format(CultureInfo.CurrentCulture, "{0}KB ({1}x{2})", (int)(pa.Size / 1024), pa.Width, pa.Height),
                dt,
                "",//location//author
                "",//comments
                "");//camera

            //
            // Actions
            //

            CreatePhotoDetailsCommands(page, isOnSlideshow);

            return page;
        }



        /// <summary>
        /// Create a details page for an photo. For Flickr
        /// NOTE: This is public to enable debug markup access.
        /// </summary>
        public DetailsPageFlickr CreatePhotoDetailsPageFlickr(GalleryItemFlickr item, bool isOnSlideshow)
        {
            DetailsPageFlickr page = new DetailsPageFlickr(item, isOnSlideshow);

            //
            // Get the full metadata on the photo.
            //
            //And
            //
            // Fill in the page's easy properties.
            //

           
            page.Title = item.Photo.Title;
            page.Summary = item.Photo.OwnerName;
            page.Background = new Image(item.Photo.MediumUrl);
            
            
            //
            // Metadata
            //
            // Now that we have all the little pieces, we can put together our
            // final metadata string.
            //
            

            //FlickrNet.Size pi = new FlickrNet.Size();
            //pi.Url = item.Photo.;
            //int w = int.Parse(Global.Imgmax, CultureInfo.CurrentCulture);
            //if (w > pi.Width) w = pi.Width;
            //page.Metadata = String.Format(CultureInfo.CurrentCulture, "{0}\n{1}\n{2:g}\n{3}\n{4}\n{5}",
            //    String.Format(CultureInfo.CurrentCulture, "{0}KB ({1}x{2})", (1024 / 1024),
            //        w, pi.Width == 0 ? w : (int)(w * pi.Height / pi.Width)),
            //    String.Format(CultureInfo.CurrentCulture, "{0}KB ({1}x{2})", (int)(1024 / 1024), pi.Width, pi.Height),
            //    dt,
            //    "",//location//author
            //    "",//comments
            //    "");//camera

            //temporary value only for testing
            page.Description = item.Photo.Title;
            
            
            page.Metadata = String.Format("Photo ID: {0}", item.Photo.PhotoId);
            //
            // Actions
            //

            CreatePhotoDetailsCommands(page, isOnSlideshow);

            return page;
        }





        /// <summary>
        /// This enum must match 1:1 with the options declared in the database.
        /// The database should only be referencing actions that this code
        /// supports.
        /// </summary>
        private enum UserPhotoDetailsActionType
        {
            Rotate = 1,
            Download = 2,
            Print = 3,
            Send = 4,
            Related = 5,
        }

        /// <summary>
        /// Create the commands for the photo details page.
        /// </summary>
        private void CreatePhotoDetailsCommands(DetailsPage page, bool isOnSlideshow)
        {
            page.SetCommands(new ArrayListDataSet(page));
            CreatePrevNextCommands(page, isOnSlideshow);

            return;
            /*
            //
            // There is a list of actions associated with each photo.
            string actionName = "Rotate";
            int actionTypeId = (int)UserPhotoDetailsActionType.Rotate;
            CreatePhotoDetailsCommand(page, actionName, actionTypeId);

            actionName = "Download";
            actionTypeId = (int)UserPhotoDetailsActionType.Download;
            CreatePhotoDetailsCommand(page, actionName, actionTypeId);

            actionName = "Print";
            actionTypeId = (int)UserPhotoDetailsActionType.Print;
            CreatePhotoDetailsCommand(page, actionName, actionTypeId);            
             * */
        }

        /// <summary>
        /// Create the commands for the photo details page. Flickr
        /// </summary>
        private void CreatePhotoDetailsCommands(DetailsPageFlickr page, bool isOnSlideshow)
        {
            page.SetCommands(new ArrayListDataSet(page));
            CreatePrevNextCommands(page, isOnSlideshow);

            return;
            /*
            //
            // There is a list of actions associated with each photo.
            string actionName = "Rotate";
            int actionTypeId = (int)UserPhotoDetailsActionType.Rotate;
            CreatePhotoDetailsCommand(page, actionName, actionTypeId);

            actionName = "Download";
            actionTypeId = (int)UserPhotoDetailsActionType.Download;
            CreatePhotoDetailsCommand(page, actionName, actionTypeId);

            actionName = "Print";
            actionTypeId = (int)UserPhotoDetailsActionType.Print;
            CreatePhotoDetailsCommand(page, actionName, actionTypeId);            
             * */
        }


        private void CreatePrevNextCommands(DetailsPage page, bool isOnSlideshow)
        {
            Command command;

            command = new Command(page, "",
              delegate(object sender, EventArgs e) { OnPhotoPrevNextActionInvoked((Command)sender, isOnSlideshow); });
            command.Data.Add("Type", "Prev");
            command.Data.Add("page", page);
            page.PrevCmd = command;

            command = new Command(page, "",
              delegate(object sender, EventArgs e) { OnPhotoPrevNextActionInvoked((Command)sender, isOnSlideshow); });
            command.Data.Add("Type", "Next");
            command.Data.Add("page", page);
            page.NextCmd = command;
        }

        private void CreatePrevNextCommands(DetailsPageFlickr page, bool isOnSlideshow)
        {
            Command command;

            command = new Command(page, "",
              delegate(object sender, EventArgs e) { OnPhotoPrevNextActionInvokedFlickr((Command)sender, isOnSlideshow); });
            command.Data.Add("Type", "Prev");
            command.Data.Add("page", page);
            page.PrevCmd = command;

            command = new Command(page, "",
              delegate(object sender, EventArgs e) { OnPhotoPrevNextActionInvokedFlickr((Command)sender, isOnSlideshow); });
            command.Data.Add("Type", "Next");
            command.Data.Add("page", page);
            page.NextCmd = command;
        }

        private void OnPhotoPrevNextActionInvoked(Command command, bool isOnSlideshow)
        {
            if ((string)command.Data["Type"] == "Prev")
            {
                GalleryItem item;
                if ((command.Data["page"] as DetailsPage).GallItem.Owner == null)
                {
                    item = (command.Data["page"] as DetailsPage).GallItem.PrevItem;
                    /*
                    item = new GalleryItem(
                    (command.Data["page"] as DetailsPage).GallItem,
                    (command.Data["page"] as DetailsPage).GallItem.Photo.PrevPhoto);
                     * */
                }
                else
                {
                    item = (command.Data["page"] as DetailsPage).GallItem.PrevItem;
                    if (item != null) item.Owner = (command.Data["page"] as DetailsPage).GallItem.Owner as ModelItem;
                    /*
                    item = new GalleryItem(
                    (command.Data["page"] as DetailsPage).GallItem.Owner as ModelItem,
                    (command.Data["page"] as DetailsPage).GallItem.Photo.PrevPhoto);
                     * */
                }

                if (item != null)
                {
                    if (DetailsPage.SlideshowTimer != null)
                    {
                        if (DetailsPage.IsPlayed) ((Timer)DetailsPage.SlideshowTimer).Stop();
                        PicasaAlbum album = (PicasaAlbum)DetailsPage.SlideshowTimer.Data["PicasaAlbum"];
                        int index = (int)DetailsPage.SlideshowTimer.Data["index"];
                        index = index <= 0 ? album.NoOfPhotos - 1 : index - 1;
                        ((Timer)DetailsPage.SlideshowTimer).Data["index"] = index;
                        Application.Current.GoToDetails(Application.Current.CurrentUser.CreatePhotoDetailsPage(item, true));
                        if (DetailsPage.IsPlayed) ((Timer)DetailsPage.SlideshowTimer).Start();
                    }
                    else
                    {
                        Application.Current.GoToDetails(CreatePhotoDetailsPage(item, isOnSlideshow));
                    }
                }
            }
            else
            {
                GalleryItem item;
                if ((command.Data["page"] as DetailsPage).GallItem.Owner == null)
                {
                    item = (command.Data["page"] as DetailsPage).GallItem.NextItem;
                    /*
                    item = new GalleryItem(
                    (command.Data["page"] as DetailsPage).GallItem,
                    (command.Data["page"] as DetailsPage).GallItem.Photo.NextPhoto);
                     * */
                }
                else
                {
                    item = (command.Data["page"] as DetailsPage).GallItem.NextItem;
                    if (item != null) item.Owner = (command.Data["page"] as DetailsPage).GallItem.Owner as ModelItem;
                    /*
                    item = new GalleryItem(
                    (command.Data["page"] as DetailsPage).GallItem.Owner as ModelItem,
                    (command.Data["page"] as DetailsPage).GallItem.Photo.NextPhoto);
                     * */
                }

                if (item != null)
                {
                    if (DetailsPage.SlideshowTimer != null)
                    {
                        if (DetailsPage.IsPlayed) ((Timer)DetailsPage.SlideshowTimer).Stop();
                        PicasaAlbum album = (PicasaAlbum)DetailsPage.SlideshowTimer.Data["PicasaAlbum"];
                        int index = (int)DetailsPage.SlideshowTimer.Data["index"];
                        index = (index + 1) % album.NoOfPhotos;
                        ((Timer)DetailsPage.SlideshowTimer).Data["index"] = index;
                        Application.Current.GoToDetails(Application.Current.CurrentUser.CreatePhotoDetailsPage(item, true));
                        if (DetailsPage.IsPlayed) ((Timer)DetailsPage.SlideshowTimer).Start();
                    }
                    else
                    {
                        Application.Current.GoToDetails(CreatePhotoDetailsPage(item, isOnSlideshow));
                    }
                }
            }
            //Application.Current.MessageBox(command.Data["page"].ToString(), command.Data["Type"].ToString());
        }

        private void OnPhotoPrevNextActionInvokedFlickr(Command command, bool isOnSlideshow)
        {
            if ((string)command.Data["Type"] == "Prev")
            {
                GalleryItemFlickr item;
                if ((command.Data["page"] as DetailsPageFlickr).GallItem.Owner == null)
                {
                    item  = (command.Data["page"] as DetailsPageFlickr).GallItem.PrevItem;
                    /*
                    item = new GalleryItemFlickr(
                    (command.Data["page"] as DetailsPageFlickr).GallItem,
                    (command.Data["page"] as DetailsPageFlickr).GallItem.PrevPhoto);
                     * */
                }
                else
                {
                    item = (command.Data["page"] as DetailsPageFlickr).GallItem.PrevItem;
                    item.Owner = (command.Data["page"] as DetailsPageFlickr).GallItem.Owner as ModelItem;
                    /*
                    item = new GalleryItemFlickr(
                    (command.Data["page"] as DetailsPageFlickr).GallItem.Owner as ModelItem,
                    (command.Data["page"] as DetailsPageFlickr).GallItem.PrevPhoto);
                     * */
                }

                if (DetailsPageFlickr.SlideshowTimer != null)
                {
                    if (DetailsPageFlickr.IsPlayed) ((Timer)DetailsPageFlickr.SlideshowTimer).Stop();
                    FlickrAlbum album = (FlickrAlbum)DetailsPageFlickr.SlideshowTimer.Data["FlickrAlbum"];
                    int index = (int)DetailsPageFlickr.SlideshowTimer.Data["index"];
                    index = index <= 0 ? (int)album.Photos.PhotosPerPage - 1 : index - 1;
                    ((Timer)DetailsPageFlickr.SlideshowTimer).Data["index"] = index;
                    Application.Current.GoToDetails(Application.Current.CurrentUser.CreatePhotoDetailsPageFlickr(item, true));
                    if (DetailsPageFlickr.IsPlayed) ((Timer)DetailsPageFlickr.SlideshowTimer).Start();
                }
                else
                {
                    Application.Current.GoToDetails(CreatePhotoDetailsPageFlickr(item, isOnSlideshow));
                }
            }
            else
            {
                GalleryItemFlickr item;
                if ((command.Data["page"] as DetailsPageFlickr).GallItem.Owner == null)
                {
                    item = (command.Data["page"] as DetailsPageFlickr).GallItem.NextItem;
                    /*
                    item = new GalleryItemFlickr(
                    (command.Data["page"] as DetailsPageFlickr).GallItem,
                    (command.Data["page"] as DetailsPageFlickr).GallItem.NextPhoto);
                     * */
                }
                else
                {
                    item = (command.Data["page"] as DetailsPageFlickr).GallItem.NextItem;
                    item.Owner = (command.Data["page"] as DetailsPageFlickr).GallItem.Owner as ModelItem;
                    /*
                    item = new GalleryItemFlickr(
                    (command.Data["page"] as DetailsPageFlickr).GallItem.Owner as ModelItem,
                    (command.Data["page"] as DetailsPageFlickr).GallItem.NextPhoto);
                     * */
                }
                if (DetailsPageFlickr.SlideshowTimer != null)
                {
                    if (DetailsPageFlickr.IsPlayed) ((Timer)DetailsPageFlickr.SlideshowTimer).Stop();
                    FlickrAlbum album = (FlickrAlbum)DetailsPageFlickr.SlideshowTimer.Data["PicasaAlbum"];
                    int index = (int)DetailsPageFlickr.SlideshowTimer.Data["index"];
                    index = (index + 1) % (int)album.Photos.PhotosPerPage;
                    ((Timer)DetailsPageFlickr.SlideshowTimer).Data["index"] = index;
                    Application.Current.GoToDetails(Application.Current.CurrentUser.CreatePhotoDetailsPageFlickr(item, true));
                    if (DetailsPageFlickr.IsPlayed) ((Timer)DetailsPageFlickr.SlideshowTimer).Start();
                }
                else
                {
                    Application.Current.GoToDetails(CreatePhotoDetailsPageFlickr(item, isOnSlideshow));
                }
            }
            //Application.Current.MessageBox(command.Data["page"].ToString(), command.Data["Type"].ToString());
        }
        
        
        
        
        
        
        
        /*
        /// <summary>
        /// Create a single photo details page command.
        /// </summary>
        private static void CreatePhotoDetailsCommand(DetailsPage page, string description, int type)
        {
            DetailsCommand command = new DetailsCommand(page, description);
            command.Type = type;
            command.Data.Add("page", page);

            // Hook up the event handler.  This handler will disambiguate
            // what the actual action that should occur based on the item's
            // action type.
            command.Invoked += delegate(object sender, EventArgs e)
            {
                OnPhotoDetailsActionInvoked((DetailsCommand)sender);
            };

            page.Commands.Add(command);
        }
         * */

        /*
        /// <summary>
        /// Called when one of the custom actions on a details page is clicked.
        /// </summary>
        private static void OnPhotoDetailsActionInvoked(DetailsCommand command)
        {
            UserPhotoDetailsActionType actionType = (UserPhotoDetailsActionType)command.Type;
            string value = command.Value;
            //int photoId = command.ItemId;

            //
            // Interpret the action.
            //

            switch (actionType)
            {
                case UserPhotoDetailsActionType.Rotate:
                {
                    break;
                }

                case UserPhotoDetailsActionType.Print:
                {
                    break;
                }

                case UserPhotoDetailsActionType.Send:
                {
                    break;
                }

                default:
                    Log.LogIt(String.Format(CultureInfo.CurrentCulture, "DetailsAction: {0}({1}): NOT YET IMPLEMENTED", actionType, value));
                    break;
            }
        }
        */
        #endregion photo Details

        #region album Details
        #endregion album Details

        /// <summary>
        /// Return Commands for items that match the search string.
        /// </summary>
        public override IList<GalleryItem> SearchPhoto(ContentPage page, string value)
        {
            if (picasaUser == null || picasaUser.NoOfAlbums == 0) return null;
            //IList<GalleryItem> results = new List<GalleryItem>();

            //
            // photos
            //
            // Search the photo table for items that have this search
            // string in their title.
            //

            VirtualList galleryList = new VirtualList(page, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompletePhotoGalleryItem);
            page.SetContent(galleryList);

            //Simple way to get the time-consuming routine to run in the next round of message loop
            //to enable the UI to update the status text
            Timer Clock;
            Clock = new Timer();
            Clock.Owner = page;
            Clock.Data.Add("albums", picasaUser.Albums);
            Clock.Data.Add("searchtext", value);
            Clock.Data.Add("index", 0);
            Clock.Data.Add("load", false);
            Clock.Interval = 1;
            Clock.Tick += new EventHandler(ScanAlbum);
            Clock.Start();

            //return results;
            return null;
        }

        private void ScanAlbum(object sender, EventArgs args)
        {
            Timer t = (Timer)sender;
            string value = (string)t.Data["searchtext"];
            SearchPage page = t.Owner as SearchPage;
            IList abs = (IList)t.Data["albums"];
            int i = (int)t.Data["index"];

            if (i < abs.Count)
            {
                PicasaAlbum ab = (PicasaAlbum)abs[i];
                page.StatusText =
                    String.Format(CultureInfo.CurrentCulture, "Searching [{0}]:[{1}]...",
                    picasaUser.Id2, ab.MyTitle);

                if ((bool)t.Data["load"])
                {
                    t.Data["load"] = false;

                    if (!ab.PhotosLoaded) ab.LoadPhotos();
                    foreach (PicasaPhoto p in ab.Photos)
                    {
                        if (p.MyTitle.ToLower(CultureInfo.CurrentCulture).Contains(value) ||
                            p.PhotoAccessor.PhotoSummary.ToLower(CultureInfo.CurrentCulture).Contains(value))
                        {
                            GalleryItem gallItem = CreatePhotoGalleryItem(page, p);
                            gallItem.PrevItem = gallItem.NextItem = gallItem;
                            //gallItem.Image = p.LoadImage(true);
                            //results.Add(gallItem);
                            page.Content.Add(gallItem);
                        }
                    }

                    i++;
                    t.Data["index"] = i;
                }
                else
                    t.Data["load"] = true;
            }
            else
            {
                SetupPrevAndNextItems(page);

                page.StatusText = "Done";
                /*
                if (page.Content.Count < 1)
                {
                    GalleryItem gallItem = new GalleryItem(page, null as PicasaAlbum);
                    gallItem.Image = null;
                    gallItem.Description = "Nothing found!";
                    gallItem.Metadata = "Try a shorter text...";
                    page.Content.Add(gallItem);
                }
                 * */
                t.Stop();
                t.Dispose();
            }

        }


        public override IList<GalleryItem> SearchPhotoFlickr(ContentPage page, string value, long pageNumber)
        {
            if (value == null || value.Trim().Length < 1) return null;

            //if (picasaUser == null || picasaUser.NoOfAlbums == 0) return null;
            //IList<GalleryItem> results = new List<GalleryItem>();

            //
            // photos
            //
            // Search the photo table for items that have this search
            // string in their title.
            //

            VirtualList galleryList = new VirtualList(page, null);
            galleryList.EnableSlowDataRequests = true;
            galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompletePhotoGalleryItemFlickr);
            page.SetContent(galleryList);

            //Simple way to get the time-consuming routine to run in the next round of message loop
            //to enable the UI to update the status text
            

            Timer Clock;
            Clock = new Timer();
            Clock.Owner = page;
            //Clock.Data.Add("albums", picasaUser.Albums);
            Clock.Data.Add("searchtext", value);
            Clock.Data.Add("index", 0);
            Clock.Data.Add("load", false);
            Clock.Data.Add("page", pageNumber);
            
            Clock.Interval = 1;
            Clock.Tick += new EventHandler(ScanAlbumFlickr);
            Clock.Start();

            //return results;
            return null;
        }

        private void ScanAlbumFlickr(object sender, EventArgs args)
        {
            Timer t = (Timer)sender;
            string value = (string)t.Data["searchtext"];
            SearchPage page = t.Owner as SearchPage;
            //IList abs = (IList)t.Data["albums"];
            int i = (int)t.Data["index"];
            FlickrAPI fa = new FlickrAPI();
            FlickrAlbum ab = null; 
            long count = 0;

            try
            {
                long pageNumber = (long)t.Data["page"];

                ab = fa.SearchPhotosByTag(value, pageNumber);
            

                if (pageNumber > 0)
                {
                    count = pageNumber;
                }
                else
                {
                    count = ab.Photos.PageNumber;
                }
            }
            catch (InvalidCastException ex)
            {

                Application.Current.MessageBox("Check if it's number", "Wrong page number");
                Log.LogIt(ex);
            }
            
            if (i < 1)
            {
                

                page.StatusText = "Flickr progress...";
                    //String.Format(CultureInfo.CurrentCulture, "Searching [{0}]:[{1}]...",
                    //picasaUser.Id2, ab.MyTitle);

                if ((bool)t.Data["load"])
                {
                    t.Data["load"] = false;


                    //foreach (Photo p in ab.Photos.PhotoCollection)
                    for (int j = 0; j < ab.Photos.PhotoCollection.Length; j++)
                    {
                        Photo p = ab.Photos.PhotoCollection.GetValue(j) as Photo;                        

                        GalleryItemFlickr gallItem = CreatePhotoGalleryItemFlickr(page, p);
                        gallItem.PrevItem = gallItem.NextItem = gallItem;
                        page.StatusText = String.Format("Adding photo {0}", p.Title.ToString());
                        page.Content.Add(gallItem);                        
                    }

                    SetupPrevAndNextItemsFlickr(page);

                    i++;
                    t.Data["index"] = i;
                }
                else
                    t.Data["load"] = true;
            }
            else
            {
                page.StatusText = "Done";
                /*
                if (page.Content.Count < 1)
                {
                    GalleryItem gallItem = new GalleryItem(page, null as PicasaAlbum);
                    gallItem.Image = null;
                    gallItem.Description = "Nothing found!";
                    gallItem.Metadata = "Try a shorter text...";
                    page.Content.Add(gallItem);
                }
                 * */
                t.Stop();
                t.Dispose();
            }

        }


        /*
                public override IList<GalleryItem> SearchAlbum(ContentPage page, string value)
                {
                    if (picasaUser == null || picasaUser.NoOfAlbums == 0) return null;
                    IList<GalleryItem> results = new List<GalleryItem>();
                    //
                    // albums
                    //
                    // Search the album table for items that have this search
                    // string in their title.
                    //

                    VirtualList galleryList = new VirtualList(page, null);
                    galleryList.EnableSlowDataRequests = true;
                    galleryList.RequestSlowDataHandler = new RequestSlowDataHandler(CompleteAlbumGalleryItem);
                    page.SetContent(galleryList);

                    foreach (PicasaAlbum ab in picasaUser.Albums)
                    {
                        if (ab.MyTitle.ToLower(CultureInfo.CurrentCulture).Contains(value) || ab.Summary.ToLower(CultureInfo.CurrentCulture).Contains(value))
                        {
                            GalleryItem gallItem = CreateAlbumGalleryItem(page, ab);
                            //gallItem.Image = ab.GetCoverImage();
                            results.Add(gallItem);
                            //galleryList.Add(gallItem);
                        }
                    }

                    return results;
                }
        */

        public PicasaUser PicasaUser
        {
            get { return picasaUser; }
            set { picasaUser = value; }
        }

        public FlickrUser FlickrUser
        {
            get { return flickrUser; }
            set { flickrUser = value; }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                // dispose managed resources                
            }
            // free native resources
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void SetupPrevAndNextItems(ContentPage page)
        {
            for (int j = 0; j < page.Content.Count; j++)
            {
                GalleryItem gallItem = page.Content[j] as GalleryItem;
                if (j > 0)
                {
                    gallItem.PrevItem = page.Content[j - 1] as GalleryItem;
                }
                else
                {
                    gallItem.PrevItem = page.Content[page.Content.Count - 1] as GalleryItem;
                }

                if (j < page.Content.Count - 1)
                {
                    gallItem.NextItem = page.Content[j + 1] as GalleryItem;
                }
                else
                {
                    gallItem.NextItem = page.Content[0] as GalleryItem;
                }
            }
        }

        private void SetupPrevAndNextItemsFlickr(ContentPage page)
        {
            for (int j = 0; j < page.Content.Count; j++)
            {
                GalleryItemFlickr gallItem = page.Content[j] as GalleryItemFlickr;
                if (j > 0)
                {
                    gallItem.PrevItem = page.Content[j - 1] as GalleryItemFlickr;
                }
                else
                {
                    gallItem.PrevItem = page.Content[page.Content.Count - 1] as GalleryItemFlickr;
                }

                if (j < page.Content.Count - 1)
                {
                    gallItem.NextItem = page.Content[j + 1] as GalleryItemFlickr;
                }
                else
                {
                    gallItem.NextItem = page.Content[0] as GalleryItemFlickr;
                }
            }
        }

        PicasaUser picasaUser;
        FlickrUser flickrUser;
    }
}
